package com.cold.legendary.mock.context.runnable;

import com.cold.legendary.mock.context.runnable.element.RunMockBeanElement;
import com.cold.legendary.mock.context.runnable.element.RunMockElement;
import com.cold.legendary.mock.context.runnable.element.SingleRunMockElement;

import java.util.ArrayList;
import java.util.List;

/**
 * @author cold
 * @since  2022/1/24
 */
public class RunContextManager {

    private static ThreadLocal<RunMockContext> runMockContextThreadLocal = new ThreadLocal<>();

    /**
     * 添加运行计数
     * @param runMockInjectBeanName 被注入的bean
     * @param runMockBeanName       被mock的bean
     * @param runMockBeanMethodName   被mock的方法名
     */
    public static void addRunMockCount(String runMockInjectBeanName, String runMockBeanName,
                                       String runMockBeanMethodName) {

        if(null == runMockContextThreadLocal) {
            runMockContextThreadLocal = new ThreadLocal<>();
        }

        if (null == runMockInjectBeanName || null == runMockBeanName || null == runMockBeanMethodName) {
            return;
        }
        RunMockContext runMockContext = runMockContextThreadLocal.get();
        if (null == runMockContext) {
            runMockContext = RunMockContext.builder().runMockElements(new ArrayList<>()).build();
        }
        runMockContext.addRunMockCount(SingleRunMockElement.builder()
                .runMockInjectBeanName(runMockInjectBeanName)
                .runMockBeanName(runMockBeanName)
                .runMockBeanMethodName(runMockBeanMethodName)
                .build());
        runMockContextThreadLocal.set(runMockContext);
    }

    /**
     * 获取当前运行的次数
     * @param runMockInjectBeanName 被注入的bean
     * @param runMockBeanName       被mock的bean
     * @param runMockBeanMethodName   被mock的方法名
     * @return 运行次数
     *
     */
    public static Integer getRunMockCount(String runMockInjectBeanName, String runMockBeanName,
                                          String runMockBeanMethodName) {
        RunMockContext runMockContext = runMockContextThreadLocal.get();
        if (null == runMockContext) {
            return 0;
        }
        List<RunMockElement> runMockElements = runMockContext.getRunMockElements();
        RunMockBeanElement runMockBeanElements = runMockElements.stream().filter(e -> e.getMockInjectBeanName().equals(runMockInjectBeanName))
                .flatMap(s -> s.getRunMockBeanElements().stream())
                .filter(e -> e.getMockBeanName().equals(runMockBeanName) && e.getMockBeanMethodName().equals(runMockBeanMethodName))
                .findFirst().orElse(null);
        if (null == runMockBeanElements) {
            return 0;
        }
        return runMockBeanElements.getRunTimes();
    }


    public static void cleanRunMockContext() {
        if(null != runMockContextThreadLocal) {
            runMockContextThreadLocal.remove();
        }
    }


}
